<template>
  <div>
    <div ref="sqlEditor"/>
    <span>
      <label for="limit">limit:</label>
      <input name="limit" id="limit" v-model="limit">
    </span>
    <div>
      <h1>参数设置</h1>
      <span v-for="(value,key,index) in filterParameters">
        <label :for="key">{{ key }}</label>
        <input v-model="filterParametersValue[key].value" name="key">
      </span>
    </div>
    <div>
      <button @click="exec">执行</button>
      <button @click="save">保存</button>
      <br>
      <label for="reportName">报表名</label><input v-model="reportName" id="reportName"/>
    </div>

    <div>
      <h1>结果</h1>
      <div>
        <vxe-table :data="execResult.data" :sort-config="{remote: true, multiple: true}" @sort-change="execSort">
          <vxe-column type="seq" title="Seq" width="60"></vxe-column>
          <vxe-column :field="item" :title="item" v-for="(item,index) in execResult.schema" sortable>
            <template #header="{column, columnIndex, $columnIndex, _columnIndex, $rowIndex}">
              <table-header-edit :column-property="column.property"
                                 :column-name="showExecResultHeader(column)"
                                 @column-change="chargeExecResultHeader"/>
            </template>
          </vxe-column>
        </vxe-table>
      </div>
    </div>
  </div>
</template>

<script>

import codemirror from 'codemirror/lib/codemirror';
import 'codemirror/mode/sql/sql';
import 'codemirror/addon/edit/matchbrackets';
import 'codemirror/addon/selection/active-line';
import 'codemirror/addon/hint/show-hint';
import 'codemirror/addon/hint/sql-hint';

import 'codemirror/lib/codemirror.css';
import 'codemirror/addon/hint/show-hint.css'
import 'codemirror/theme/darcula.css'
import request from "@/utils/request";
import TableHeaderEdit from "@/components/TableHeaderEdit";

const pattern = /\\?\${([^}]+)}/gm;

export default {
  name: "Definition",
  components: {
    TableHeaderEdit
  },
  mounted() {
    if (this.id) {
      this.load()
    }

    this.editor = codemirror(this.$refs.sqlEditor, {
      mode: 'text/x-mysql',
      indentWithTabs: true,
      smartIndent: true,
      lineNumbers: true,
      matchBrackets: true,
      cursorHeight: 1,
      lineWrapping: true,
      readOnly: false,
      // theme: 'darcula',
      autofocus: true,
      value: this.sql,
      extraKeys: {Ctrl: 'autocomplete'},
      hintOptions: {
        completeSingle: false,
        alignWithWord: false,
        tables: {
          'order_data': ['order_id', 'good_name']
        }
      }
    });
    this.editor.on("update", (editor) => {
      this.sql = editor.getValue();
    });
    this.filterParametersAnalysis(this.sql);
  },
  beforeUnmount() {
  },
  watch: {
    sql: function (newValue) {
      this.filterParametersAnalysis(newValue)
    }
  },
  data() {
    return {
      editor: null,
      sql: "",
      filterParametersValue: {},
      filterParameters: {},
      id: this.$route.params.id,
      reportName: '',
      execResult: {},
      headerNames: {},
      sorts: [],
      limit: 100
    };
  },
  methods: {
    filterParametersAnalysis(sql) {
      this.filterParameters = {}
      sql.replace(pattern, (match, propName) => {
        if (!this.filterParameters[propName]) {
          this.filterParameters[propName] = {}
          this.filterParametersValue[propName] = {}
        }
      });

    },
    showExecResultHeader(column) {
      if (this.headerNames) {
        if (this.headerNames[column.property])
          return this.headerNames[column.property].headerName;
      }
      return column.property;
    },
    chargeExecResultHeader(columnProperty, columnName) {
      if (!this.headerNames) {
        this.headerNames = {}
      }
      this.headerNames[columnProperty] = {headerField: columnProperty, headerName: columnName};
    },
    buildFilterParameters() {
      const parameters = [];
      for (let propName in this.filterParameters) {
        parameters.push({
          "parameterName": propName,
          "parameterValue": this.filterParametersValue[propName].value
        })
      }
      return parameters;
    },
    buildExecSort() {
      return this.sorts;
    },
    exec() {
      request.post("http://localhost:8090/custom/exec", {
        sqlTemplate: this.sql,
        parameters: this.buildFilterParameters(),
        sorts: this.buildExecSort(),
        limit: {
          limit: this.limit
        }
      }).then((data) => {
        this.execResult = {};
        if (data.data.code !== 200) {
          alert(data.data.msg)
        }
        this.execResult = data.data.data
      })
    },
    execSort({sortList}) {
      this.sorts = [];
      for (let sort of sortList) {
        this.sorts.push({
          "fieldName": sort.property,
          "orderType": sort.order
        })
      }
      this.exec();
    },
    save() {
      if (!this.execResult.schema || this.execResult.schema.length <= 0) {
        alert("请先正确执行")
        return;
      }
      if (this.reportName.length <= 0) {
        alert("请先设置报表名")
        return;
      }
      let headerNamesTmp = {};
      for (let headerNamesKey in this.headerNames) {
        if (this.execResult.schema.includes(headerNamesKey)) {
          headerNamesTmp[headerNamesKey] = this.headerNames[headerNamesKey];
        }
      }

      if (this.id) {
        request.post("http://localhost:8090/custom/" + this.id, {
          sqlTemplate: this.sql,
          configure: {
            parameters: this.buildFilterParameters(),
            headerNames: headerNamesTmp
          },
          reportName: this.reportName
        }).then((data) => {
          if (data.data.code !== 200) {
            alert(data.data.msg)
          }
          alert(data.data.msg)
        })
      } else {
        request.post("http://localhost:8090/custom/save", {
          sqlTemplate: this.sql,
          configure: {
            parameters: this.buildFilterParameters(),
            headerNames: headerNamesTmp
          },
          reportName: this.reportName
        }).then((data) => {
          if (data.data.code !== 200) {
            alert(data.data.msg)
          }
          alert(data.data.msg)
        })
      }
    },
    load() {
      request.get("http://localhost:8090/custom/" + this.id).then((data) => {
        if (data.data.code !== 200) {
          alert(data.data.msg)
        }
        this.sql = data.data.data.sqlTemplate;
        this.headerNames = data.data.data.configure.headerNames;
        this.reportName = data.data.data.reportName;
        let parameters = data.data.data.configure.parameters;
        for (let parameter of parameters) {
          this.filterParametersValue[parameter.parameterName] = {value: parameter.parameterValue};
        }
        this.editor.setValue(this.sql);
      })
    }
  }
}
</script>

<style scoped>

</style>